home *** CD-ROM | disk | FTP | other *** search
-
- /* utmp.c Shareware Copyright by Sam Lantinga 10/6/93 */
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <utmp.h>
- #include <stdio.h>
-
- #ifdef DEBUG_UTMP
- #undef UTMP_FILE
- #define UTMP_FILE "/tmp/utmp"
- #else
- #ifndef UTMP_FILE
- #define UTMP_FILE "/etc/utmp"
- #endif /* UTMP_FILE */
- #endif /* DEBUG_UTMP */
-
-
- /* Remove us from the utmp file, saving our entry to replace later */
-
- static struct utmp saved_utmp;
- static int utmp_saved=0;
- static char saved_tty[128];
-
- int remove_me()
- {
- struct utmp ut;
- char *tty;
- time_t now;
-
- if ( (! isatty(0)) || ((tty=(char *)ttyname(0)) == NULL) )
- return(-1);
-
- /* Retrieve our utmp record */
- (void) time(&now);
- if ( get_utmp(tty, &ut) == 0 ) {
- /* Save the utmp entry and tty pathname */
- utmp_saved=1;
- d_copy((char *)&ut, (char *)&saved_utmp, sizeof(ut));
- strcpy(saved_tty, tty);
-
- /* Clean out the entry and return */
- ut.ut_name[0]='\0';
- ut.ut_time=now;
- #ifdef USER_PROCESS
- ut.ut_type = DEAD_PROCESS;
- #endif
- #ifdef HAVE_UTHOST
- ut.ut_host[0]='\0';
- #endif
- return(set_utmp(tty, &ut));
- }
- /* Nothing to clean out, good. */
- return(0);
- }
-
-
- int replace_me()
- {
- if ( utmp_saved )
- return(set_utmp(saved_tty, &saved_utmp));
- return(0);
- }
-
- int get_utmp(tty, save)
- char *tty;
- struct utmp *save;
- {
- int fd;
- char *ttyptr;
- struct utmp ut;
-
- /* See if we can open the utmp file */
- if ( (fd=open(UTMP_FILE, O_RDWR)) < 0 )
- return(-1);
-
- /* Get the ttyxy form of the tty pathname if possible. */
- if ( *tty == '/' ) {
- for ( ttyptr=(tty+1); *ttyptr; ++ttyptr ) {
- if ( *ttyptr == '/' )
- break;
- }
- if ( *ttyptr == '/' )
- ++ttyptr;
- } else
- ttyptr=tty;
-
- while (read(fd,(char *) &ut, sizeof(ut)) == sizeof(ut)) {
- if (strncmp(ttyptr, ut.ut_line, sizeof(ut.ut_line)) == 0) {
- /* Break out; we've found our entry! */
- if ( save )
- d_copy((char *)&ut, save, sizeof(ut));
- close(fd);
- return(0);
- }
- }
- /* We never found an entry for our tty */
- close(fd);
- return(-1);
- }
-
- int set_utmp(tty, save)
- char *tty;
- struct utmp *save;
- {
- int fd, found=0;
- char *ttyptr;
- struct utmp ut;
-
- /* See if we can open the utmp file */
- if ( (fd=open(UTMP_FILE, O_RDWR)) < 0 )
- return(-1);
-
- /* Get the ttyxy form of the tty pathname if possible. */
- if ( *tty == '/' ) {
- for ( ttyptr=(tty+1); *ttyptr; ++ttyptr ) {
- if ( *ttyptr == '/' )
- break;
- }
- if ( *ttyptr == '/' )
- ++ttyptr;
- } else
- ttyptr=tty;
-
- while (read(fd,(char *) &ut, sizeof(ut)) == sizeof(ut)) {
- if (strncmp(ttyptr, ut.ut_line, sizeof(ut.ut_line)) == 0) {
- found=1;
- lseek(fd, -(long)sizeof(struct utmp), 1);
- break;
- }
- }
-
- /* Add a new entry to the utmp file if we can't find our entry */
- if ( ! found )
- { /* Reopen to avoid a race with other end-of-utmp entries. */
- (void) close(fd);
- if ( (fd=open(UTMP_FILE, (O_RDWR|O_APPEND))) < 0 )
- return -1;
- }
-
- if (write(fd, (char *)save, sizeof(*save)) != sizeof(*save)) {
- (void) close(fd);
- return -1;
- }
- return(close(fd));
- }
-
-
- /* Set up a utmp entry and tty for a user */
-
- int addutmp(user, uid, tty)
- char *user; /* The user to add to the utmp file */
- int uid; /* The uid corresponding to user */
- char *tty; /* /dev/ttyxx */
- {
- struct stat sb;
- struct utmp ut;
- char *ttyptr;
-
- /* Retrieve any existing utmp entry */
- d_zero((char *)&ut, sizeof(ut));
- (void) get_utmp(tty, &ut);
-
- /* Get the ttyxy form of the tty pathname if possible. */
- if ( *tty == '/' ) {
- for ( ttyptr=(tty+1); *ttyptr; ++ttyptr ) {
- if ( *ttyptr == '/' )
- break;
- }
- if ( *ttyptr == '/' )
- ++ttyptr;
- } else
- ttyptr=tty;
-
- /* Customize the utmp entry */
- strncpy(ut.ut_name, user, sizeof(ut.ut_name));
- strncpy(ut.ut_line, ttyptr, sizeof(ut.ut_line));
- #ifdef USER_PROCESS
- ut.ut_type=USER_PROCESS;
- ut.ut_pid=getpid();
- #endif
- #if defined(HAVE_UTHOST)
- /* remove_me() should be called before this function */
- if ( utmp_saved )
- strncpy(ut.ut_host, saved_utmp.ut_host, sizeof(ut.ut_host));
- #endif
- (void) time(&ut.ut_time);
-
- #if !defined(SOLARIS) && !defined(IRIX)
- /* Solaris and Irix machines do this automatically */
- /* Change the ownership and mode of the tty */
- if ( stat(tty, &sb) == 0 ) {
- (void) chmod(tty, 0620); /* crw--w---- */
- (void) chown(tty, uid, sb.st_gid);
- }
- #endif
- return(set_utmp(tty, &ut));
- }
-
-
- /* End a utmp entry and tty for a user and a tty */
-
- int delutmp(user, tty)
- char *user;
- char *tty; /* /dev/ttyxx */
- {
- struct stat sb;
- struct utmp ut;
- int retval=0;
-
- /* Retrieve any existing utmp entry */
- d_zero((char *)&ut, sizeof(ut));
- if ( get_utmp(tty, &ut) == 0 ) {
- /* Clear the utmp entry */
- ut.ut_name[0]='\0';
- #ifdef USER_PROCESS
- ut.ut_type=DEAD_PROCESS;
- #endif
- #if defined(HAVE_UTHOST)
- ut.ut_host[0]='\0';
- #endif
- (void) time(&ut.ut_time);
- retval=set_utmp(tty, &ut);
- }
-
- #if !defined(SOLARIS) && !defined(IRIX)
- /* Solaris and Irix machines do this automatically */
- /* Reset the owner and mode of the tty */
- if ( stat(tty, &sb) == 0 ) {
- (void) chmod(tty, 0666); /* crw-rw-rw- */
- (void) chown(tty, 0, sb.st_gid);
- }
- #endif
- return(retval);
- }
-
-
-